import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import cross_val_predict, train_test_split
from sklearn import datasets
from sklearn import metrics
import numpy as np

mpl.rcParams['font.family'] = ['sans-serif']
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus']=False

# 读取数据
names = ['成色', '市场价格', '颜色', '材质', '是否限量', '回收价格']
feature_names = ['市场价格']
target_name = ['回收价格']
df = pd.read_csv('data.csv', names=names, sep='\t', header=0)
X = pd.DataFrame(df, columns=feature_names)
y = pd.DataFrame(df, columns=target_name)

# 模型调优
# 1、去掉回收价格小于1000的异常值
# 2、去掉回收价高于市场价的值
# 3、去掉回收价格高于10000的异常值
drop_index = df[((df['回收价格'] < 1000))|
                (df['回收价格'] > 10000)|
                (df['回收价格'] > df['市场价格'])|
                (df['成色'] != 90)
                ].index.values

X = X.drop(drop_index)
y = y.drop(drop_index)


opt = 'S级'

# 数据归一化
# 先去掉异常值再归一化
# X 归一到 [0, 1]
from sklearn import preprocessing
min_max_scaler = preprocessing.MinMaxScaler()
X = min_max_scaler.fit_transform(X)

print('样本集:', X.shape)

# 划分训练集和测试集
# 这里划分训练集和测试集的参数random_state都是1，表示随机分配的数据是同一组
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1)
print('训练集:', X_train.shape)
print('测试集:', X_test.shape)

# 模型训练
# 对训练集进行训练
lr = LinearRegression()
lr.fit(X_train, y_train)

print('斜率:', lr.coef_)
print('截距:', lr.intercept_)


# 模型评估
# 对预测集进行预测
y_pred = lr.predict(X_test)
MSE = metrics.mean_squared_error(y_test, y_pred)
RMSE = np.sqrt(MSE)
MAE = metrics.mean_absolute_error(y_test, y_pred)
# MAPE和SMAPE需要自己实现
def mape(y_test, y_pred):
    return np.mean(np.abs((y_pred - y_test) / y_test)) * 100
def smape(y_test, y_pred):
    return 2.0 * np.mean(np.abs(y_pred - y_test) / (np.abs(y_pred) + np.abs(y_test))) * 100
MAPE = mape(y_test, y_pred)
SMAPE = smape(y_test, y_pred)

print('均方误差 MSE:', MSE)
print('均方根误差 RMSE:', RMSE)
print('平均绝对误差 MAE:', MAE)
print('平均绝对百分比误差 MAPE:', MAPE[0])
print('对称平均绝对百分比误差 SMAPE:', SMAPE[0])

# 观察预测数据与测试数据
plt.figure(1, figsize=(10,5))
plt.plot(range(len(y_test)), y_test, 'r', label='真实值')
plt.plot(range(len(y_test)), y_pred, 'b', label='预测值')
plt.legend()
plt.savefig('/Users/pg/Documents/Paper/images/估价一元-折线图-%s.png'%opt)

plt.figure(2)
plt.scatter(y_test, y_pred)
plt.plot([y_test.min(),y_test.max()], [y_test.min(),y_test.max()], 'k--')
plt.xlabel('真实值')
plt.ylabel('预测值')
plt.savefig('/Users/pg/Documents/Paper/images/估价一元-散点图-%s.png'%opt)






